package Tools.Lighting;

import java.util.ArrayList;
import java.util.List;

import GameMath.GSize;

/** Light manager class
 * @author Aikidos
 */
public class LightManager {
	/** List of light */
	private List<ILight> _lstLights = new ArrayList<ILight>();
	
	/** Light map */
	private LightMap _lightMap;
	
	/** Enabled light */
	private boolean _isEnabled = true;
	
	/** Solid map */
	private boolean[][] _solidMap;
	
	/** Recalculate lighting timeout */
	private int _recalcTimeout = 0;
	
	/** Recalculate timer */
	private int _recalcTimer = 0;
	
	/** Lighting recalculate is automatic? **/
	private boolean _autoRecalc = true;
	
	/** Initialize light manager
	 * @param lightMapSize - Size of light map
	 */
	public void initLightMap(GSize lightMapSize) {
		// Create light map
		_lightMap = new LightMap(lightMapSize);
	}
	
	/** Returns light map
	 * @return Light map
	 */
	public LightMap getLightMap() {
		return _lightMap;
	}
	
	/** Returns list of light
	 * @return List of light
	 */
	public List<ILight> getLights() {
		return _lstLights;
	}
	
	/** Returns solid map
	 * @return Solid map
	 */
	public boolean[][] getSolidMap() {
		return _solidMap;
	}
	
	/** Returns recalculate lighting timeout
	 * @return Recalculate lighting timeout
	 */
	public float getRecalcTimeout() {
		return _recalcTimeout;
	}
	
	/** Lighting recalculate is automatic? */
	public boolean isAutoRecalc() {
		return _autoRecalc;
	}
	
	/** Returns true if lighting is enabled
	 * @return True if lighting is enabled
	 */
	public boolean isEnabled() {
		return _isEnabled;
	}
	
	/** Set map of solid blocks
	 * @param map - Solid map
	 */
	public void setSolidMap(boolean[][] map) {
		_solidMap = map;
	}
	
	/** Set recalculate lighting timeout
	 * @param timeout - Recalculate lighting timeout
	 */
	public void setRecalcTimeout(int timeout) {
		_recalcTimeout = timeout;
	}
	
	/** Set automatic recalculate lighting 
	 * @param value - True if automatic recalculate lighting is on
	 */
	public void setAutoRecalc(boolean value) {
		_autoRecalc = value;
	}
	
	/** Disable lighting */
	public void disable() {
		_isEnabled = false;
	}
	
	/** Enable lighting */
	public void enable() {
		_isEnabled = true;
	}
	
	/** Add new light
	 * @param light - Light
	 */
	public void addLight(ILight light) {
		_lstLights.add(light);
	}
	
	/** Remove light 
	 * @param light - Light
	 */
	public void removeLight(ILight light) {
		_lstLights.remove(light);
	}
	
	/** Calculate lighting */
	public void calcLighting() {
		_lightMap.clear();
		
		if (_isEnabled) {
			for (ILight light : _lstLights) {
				light.calcLighting(_lightMap, _solidMap);
			}
		} else {
			for (int i = 0; i < _lightMap.getSize().width; i++) {
				for (int j = 0; j < _lightMap.getSize().height; j++) {
					_lightMap.getMap()[i][j].fullIlluminated();
				}
			}
		}
	}
	
	/** Update light manager 
	 * @param delta - Time delta
	 */
	public void update(int delta) {
		// Update lights
		for (ILight light : _lstLights) {
			light.update(delta);
		}
		
		// Recalculate light map
		if (_autoRecalc) {
			if (_recalcTimeout == 0)
				calcLighting();
			else {
				if (_recalcTimer >= _recalcTimeout) {
					_recalcTimer = 0;

					calcLighting();
				} else
					_recalcTimer += delta;
			}
		}
	}
	
}
